import SkuEntity from '@/feature/pdt/domain/SkuEntity'

export default class SkuEntityCollection {
  constructor(values = []) {
    this.init(values)
    this.propertyListCount = -1
  }

  get isSingleSku() {
    return this.values.length === 1
  }

  init(values = []) {
    if (!values || values.length === 0) {
      this.values = [new SkuEntity()]
    } else {
      this.values = values.map(el => new SkuEntity(el))
      // this.initSkuList = values
      // this.values = []
    }
  }

  getValues() {
    return this.values.map(el => el.getSkuRow())
  }

  get totalStock() {
    return this.values.reduce((r, a) => {
      return r + parseInt(a.finalStock)
    }, 0) || 0
  }

  get price() {
    return Math.min(...this.values.map(el => el.price))
  }

  batchSetField(propValueMap, field, fieldValue, isBatchAddStock = false) {
    this.values.forEach(value => {
      value.setMatchedFieldValue(propValueMap, field, fieldValue)
      if (field === 'deltaStock') {
        value.isAddStock = isBatchAddStock
        value.calcFinalStock()
      }
    })
  }

  // 删除多余的sku
  removeExtraValues(propertyList) {
    const idList = propertyList.reduce((r, a) => {
      r = r.concat(a.options.map(el => el.id))
      return r
    }, [])
    this.values = this.values.filter(v => v.valueIdsIn(idList))
  }

  calcValues(propertyList) {
    if (propertyList.length === 0) {
      this.init()
    } else {
      let values = []
      const rowsCount = propertyList.reduce((r, a) => r * a.options.length, 1) || 1
      let propertySizeChanged = false
      if (this.propertyListCount === -1 || this.propertyListCount === propertyList.length) {
        if (rowsCount === this.values.length) {
          values = [...this.values]
          values.forEach(v => v.clearSalePropValues())
        } else {
          this.removeExtraValues(propertyList)
        }
      } else {
        this.propertyListCount = propertyList.length
        propertySizeChanged = true
      }
      let groupCount = 1
      for (let i = 0; i < propertyList.length; i++) {
        const saleProp = propertyList[i]
        const salePropValueList = saleProp.options
        const rowSpan = rowsCount / salePropValueList.length / groupCount
        const groupSize = rowsCount / groupCount // 分组
        for (let g = 0; g < groupCount; g++) {
          for (let j = 0; j < salePropValueList.length; j++) {
            for (let k = 0; k < rowSpan; k++) {
              const idx = groupSize * g + j * rowSpan + k
              if (!values[idx]) {
                values[idx] = new SkuEntity(saleProp)
              }
              values[idx].setSalePropValue({
                ...salePropValueList[j],
                rowSpan: k === 0 ? rowSpan : 0
              })
            }
          }
        }
        groupCount *= salePropValueList.length // 累计分组
      }
      if (rowsCount !== this.values.length && !propertySizeChanged) {
        for (let j = 0; j < values.length; j++) {
          const value = values[j]
          const founded = this.values.find(el => el.isSaleProValuesEq(value.values))
          if (founded) {
            founded.values = value.values
            values[j] = founded
          }
        }
      }
      this.values.length = 0
      this.values.push(...values)
    }
  }

  getOrCreateSkuEntity(saleProp, salePropValue) {
    let result = this.values.find(el => el.isSaleProValuesEq(salePropValue))
    if (!result) {
      result = new SkuEntity(saleProp)
    } else {
      result.clearSalePropValues()
    }
    return result
  }

  validate() {
    let i = 1
    for (const value of this.values) {
      value.validate(i)
      i++
    }
  }

  maxSkuPrice() {
    return Math.round(this.values.reduce((r, a) => {
      return r < a.price ? a.price : r
    }, 0) * 100) / 100
  }

  assertMaxPriceLessThan(marketPrice) {
    let minPrice = this.values[0].price
    let foundedIdx = 0
    for (let i = 1; i < this.values.length; i++) {
      if (minPrice > this.values[i].price) {
        minPrice = this.values[i].price
        foundedIdx = i
      }
    }
    if (this.values[foundedIdx].price >= marketPrice) {
      throw new Error('第' + (foundedIdx + 1) + '行规格的价格高于或等于您设置的参考价，请修改')
    }
  }
}
